package com.yequan.leetcode.tree.levelOrder_102;

import com.yequan.leetcode.tree.TreeNode;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * //给你一个二叉树，请你返回其按 层序遍历 得到的节点值。 （即逐层地，从左到右访问所有节点）。
 * //
 * //
 * //
 * // 示例：
 * //二叉树：[3,9,20,null,null,15,7],
 * //
 * //     3
 * //   / \
 * //  9  20
 * //    /  \
 * //   15   7
 * //
 * //
 * // 返回其层次遍历结果：
 * //
 * // [
 * //  [3],
 * //  [9,20],
 * //  [15,7]
 * //]
 * //
 * // Related Topics 树 广度优先搜索
 * <p>
 * <p>
 * //leetcode submit region begin(Prohibit modification and deletion)
 *
 * @author : Administrator
 * @date : 2020/4/4
 */
public class LevelOrder {


    public List<List<Integer>> levelOrder1(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        bfs2(root, 0, res);
        return res;
    }

    public void bfs2(TreeNode node, int level, List<List<Integer>> res) {
        if (null != node) {
            if (level <= res.size()) {
                res.add(new ArrayList<>());
            }
            res.get(level).add(node.val);
            if (null != node.left) {
                bfs2(node.left, level + 1, res);
            }
            if (null != node.right) {
                bfs2(node.right, level + 1, res);
            }
        }
    }

    /**
     * 使用队列广度优先遍历
     *
     * @param root
     * @return
     */
    public List<List<Integer>> levelOrder2(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            List<Integer> currentLevelRes = new ArrayList<Integer>();
            int currentLevelSize = queue.size();
            for (int i = 0; i < currentLevelSize; i++) {
                TreeNode node = queue.poll();
                currentLevelRes.add(node.val);
                if (null != node.left) {
                    queue.offer(node.left);
                }
                if (null != node.right) {
                    queue.offer(node.right);
                }
            }
            res.add(currentLevelRes);
        }
        return res;
    }

}
